import xml.etree.ElementTree as ET
from lxml import etree
# 解析ARXML文件
def parse_arxml(file_path):
    tree = ET.parse(file_path)
    root = tree.getroot()
    return root

# 解析CS_前缀的类型
def resolve_cs_type(root, type_name):
    # 尝试查找枚举类型
    for compu_method in root.findall('.//{http://autosar.org/schema/r4.0}COMPU-METHOD'):
        if compu_method.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text == type_name:
            return 'int'  # 假设CS_前缀的类型是枚举类型，用int替代
    # 尝试查找自定义类型
    for data_type in root.findall('.//{http://autosar.org/schema/r4.0}STD-CPP-IMPLEMENTATION-DATA-TYPE'):
        if data_type.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text == type_name:
            return type_name  # 假设CS_前缀的类型是自定义类型
    return 'int'  # 默认情况下用int替代

# 提取所有结构体及其成员
def extract_structures(root):
    structures = {}
    for data_type in root.findall('.//{http://autosar.org/schema/r4.0}STD-CPP-IMPLEMENTATION-DATA-TYPE'):
        if data_type.find('{http://autosar.org/schema/r4.0}CATEGORY').text == 'STRUCTURE':
            struct_name = data_type.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text
            members = []

            for sub_element in data_type.findall('.//{http://autosar.org/schema/r4.0}CPP-IMPLEMENTATION-DATA-TYPE-ELEMENT'):
                member_name = sub_element.find('{http://autosar.org/schema/r4.0}SHORT-NAME').text
                member_type_ref = sub_element.find('.//{http://autosar.org/schema/r4.0}TYPE-REFERENCE-REF')
                if member_type_ref is not None:
                    member_type = member_type_ref.text.split('/')[-1]
                    if member_type.startswith('CS_'):
                        member_type = resolve_cs_type(root, member_type)
                else:
                    member_type = 'int'  # 默认类型
                    print(f"Warning: TYPE-REFERENCE-REF not found for member {member_name} in struct {struct_name}, using default type 'int'")
                desc = sub_element.find('{http://autosar.org/schema/r4.0}DESC/{http://autosar.org/schema/r4.0}L-2').text if sub_element.find('{http://autosar.org/schema/r4.0}DESC/{http://autosar.org/schema/r4.0}L-2') is not None else ''
                members.append((member_name, member_type, desc))

            structures[struct_name] = members
    return structures


# 生成C语言头文件代码
def generate_c_header(structures):
    header_code = []
    header_code.append('#ifndef VAR_H\n')
    header_code.append('#define VAR_H\n')
    header_code.append('#include <stdint.h>\n')

    for struct_name, members in structures.items():
        header_code.append(f'typedef struct {{\n')
        for member_name, member_type, desc in members:
            if desc:
                header_code.append(f'    // {desc}\n')
            header_code.append(f'    {member_type} {member_name};\n')
        header_code.append(f'}} {struct_name};\n')

    # for enum_name, enum_values in enums.items():
    #     header_code.append(f'typedef enum {{\n')
    #     for enum_value in enum_values:
    #         header_code.append(f'    {enum_value},\n')
    #     header_code.append(f'}} {enum_name};\n')

    # for array_name, (element_type, array_size, desc) in arrays.items():
    #     if desc:
    #         header_code.append(f'// {desc}\n')
    #     header_code.append(f'typedef {element_type} {array_name}[{array_size}];\n')

    header_code.append('#endif // VAR_H\n')
    return ''.join(header_code)

def generate_c_enum_definition(element, enum_name):
    # 查找 COMPU-SCALES 标签
    compu_scales = element.findall('.//{http://autosar.org/schema/r4.0}COMPU-SCALE')
    enum_lines = [f"typedef enum {{\n"]
    typedef_lines = []
    if compu_scales:
        for compu_scale in compu_scales:
            lower_limit = compu_scale.find('.//{http://autosar.org/schema/r4.0}LOWER-LIMIT')
            vt = compu_scale.find('.//{http://autosar.org/schema/r4.0}VT')
            if lower_limit is not None and vt is not None:
                enum_lines.append(f"    {vt.text} = {lower_limit.text},\n")
        enum_lines.append(f"}} {enum_name};\n")
        
        # 生成 typedef 语句
        typedef_lines.append(f"typedef {enum_name} {enum_name.replace('_Enum', '')};\n")
        
        return ''.join(enum_lines + typedef_lines)
    return ""

def parse_arxml_enum(file_path):
    # 解析 ARXML 文件
    tree = etree.parse(file_path)
    root = tree.getroot()

    # 定义命名空间
    namespace = {'autosar': 'http://autosar.org/schema/r4.0'}

    # 使用 XPath 查找所有带有 _Enum 尾缀的 SHORT-NAME 标签
    enum_names = root.xpath(".//autosar:SHORT-NAME[re:match(text(), '.*_Enum$')]", namespaces={'re': 'http://exslt.org/regular-expressions', 'autosar': 'http://autosar.org/schema/r4.0'})

    if enum_names:
        enum_definitions = []
        for enum_name in enum_names:
            # 获取枚举名称
            enum_name_text = enum_name.text
            # 获取枚举的父标签
            parent = enum_name.getparent()
            # 查找 COMPU-INTERNAL-TO-PHYS 标签
            compu_internal_to_phys = parent.find('.//{http://autosar.org/schema/r4.0}COMPU-INTERNAL-TO-PHYS')
            if compu_internal_to_phys is not None:
                # 解析并生成 C 语言风格的枚举定义
                enum_definition = generate_c_enum_definition(compu_internal_to_phys, enum_name_text)
                enum_definitions.append(enum_definition)
            else:
                print(f"COMPU-INTERNAL-TO-PHYS not found for {enum_name_text}.")

        # 将所有枚举定义写入 var.h 文件
        with open('var.h', 'a') as f:
            f.write('\n\n'.join(enum_definitions))
        print("C language enum definitions have been written to var.h")
    else:
        print("No SHORT-NAME tags with _Enum suffix found in the ARXML file.")

# 主函数
def main():
    file_path = 'InterDomain.arxml'
    root = parse_arxml(file_path)
    structures = extract_structures(root)
    # enums = extract_enums(root)
    # arrays = extract_arrays(root)
    header_code = generate_c_header(structures)
    
    # 将结果写入var.h文件
    with open('var.h', 'w') as file:
        file.write(header_code)

    parse_arxml_enum("InterDomain.arxml")

if __name__ == '__main__':
    main()

